package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.ModelConverter;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.common.util.StringUtil;
import cn.com.acca.ma.model.ConceptBoard;
import cn.com.acca.ma.model.ConceptBoardIndex;
import cn.com.acca.ma.model.RelStockInfoConceptBoard;
import cn.com.acca.ma.model.StockInfo;
import cn.com.acca.ma.service.ConceptBoardIndexService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ConceptBoardIndexServiceImpl extends BaseServiceImpl<ConceptBoardIndexServiceImpl, ConceptBoardIndex> implements ConceptBoardIndexService {
    @Override
    public String listToString(List list) {
        return null;
    }

    /**
     * 调用akshare接口，海量地保存数据（concept_board_index表和concept_board表），更新stock_info表的concept_board_id列
     */
//    @Override
//    public void writeConceptBoardIndexAndConceptBoardAndUpdateConceptBoardIdInStockInfo_akShare() {
//        logger.info("开始调用akshare接口，海量地保存数据（concept_board_index表和concept_board表），更新stock_info表的concept_board_id列");
//
//        String filePath = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.file.path");
//        String findCurrentAllConceptBoardNameAndCode = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findCurrentAllConceptBoardNameAndCode");
//        String findConceptBoardIndexByNameAndBeginDateAndEndDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findConceptBoardIndexByNameAndBeginDateAndEndDate");
//        String beginDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findConceptBoardIndexByNameAndBeginDateAndEndDate.beginDate");
//        String endDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findConceptBoardIndexByNameAndBeginDateAndEndDate.endDate");
//        String findStockByConceptBoardName = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findStockByConceptBoardCode");
//
//        Process process = null;
//        BufferedReader in = null;
//        try {
//            // 调用adam3的接口，查询当前所有概念板块的name和code
//            String[] parameterArray = new String[]{"python", filePath, "api",  findCurrentAllConceptBoardNameAndCode};
//            process = Runtime.getRuntime().exec(parameterArray);
//            in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
//            StringBuffer stringBuffer = new StringBuffer();
//            String actionStr;
//            while ((actionStr = in.readLine()) != null) {
//                stringBuffer.append(actionStr);
//                logger.info("接口返回值：" + actionStr);
//            }
//
//            // 解析
//            List<ConceptBoard> conceptBoardWithNameAndCodeList = JSONObject.parseArray(stringBuffer.toString(), ConceptBoard.class);
//
//            // 删除concept_board表中的所有记录
//            conceptBoardDao.truncateTable();
//
//            // 向表concept_board中批量插入记录
//            List<ConceptBoard> insertConceptBoardList = new ArrayList<>();
//            for (ConceptBoard conceptBoard: conceptBoardWithNameAndCodeList){
//                ConceptBoard insertConceptBoard = new ConceptBoard();
//                insertConceptBoard.setName(conceptBoard.getName());
//                insertConceptBoard.setMyquantCode(conceptBoard.getMyquantCode());
//                insertConceptBoard.setCreateTime(new Date());
//                insertConceptBoardList.add(insertConceptBoard);
//            }
//            conceptBoardDao.batchSave(insertConceptBoardList);
//
//            // 删除concept_board_index表中的所有记录
//            conceptBoardIndexDao.truncateTable();
//
//            // 调用akshare接口，根据name、begin_date和end_date，海量地获取数据
//            for (ConceptBoard conceptBoard: conceptBoardWithNameAndCodeList){
//                parameterArray = new String[]{"python", filePath, "api",  findConceptBoardIndexByNameAndBeginDateAndEndDate,
//                        conceptBoard.getName(), conceptBoard.getMyquantCode(), beginDate, endDate};
//                process = Runtime.getRuntime().exec(parameterArray);
//                in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
//                stringBuffer = new StringBuffer();
//                actionStr = null;
//                while ((actionStr = in.readLine()) != null) {
//                    stringBuffer.append(actionStr);
//                    logger.info("接口返回值：" + actionStr);
//                }
//
//                if (StringUtils.isEmpty(stringBuffer.toString())){
//                    logger.warn("概念板块[" + conceptBoard.getName() + "," + conceptBoard.getMyquantCode() + "]在日期[" + beginDate + "]和[" + endDate + "]之间没有数据");
//                    continue;
//                }
//
//                // 解析
//                List<ConceptBoardIndex> insertConceptBoardIndexList = ModelConverter.stringToConceptBoardIndexList(stringBuffer.toString(), conceptBoard.getAkshareCode());
//
//                // 批量插入ConceptBoardIndex对象
//                if (null != insertConceptBoardIndexList && insertConceptBoardIndexList.size() > 0){
//                    conceptBoardIndexDao.batchSave(insertConceptBoardIndexList);
//                }
//            }
//
//            // 将stock_info表的concept_board_id字段设置为null
////            stockInfoDao.setConceptBoardIdNull();
//
//            // 删除rel_stock_info_concept_board表的所有记录
//            relStockInfoConceptBoardDao.truncateTable();
//
//            // 向表rel_stock_info_concept_board中添加记录，注意：有的股票可能在stock_info表中没有记录
//            for (ConceptBoard conceptBoard: conceptBoardWithNameAndCodeList){
//                parameterArray = new String[]{"python", filePath, "api",  findStockByConceptBoardName, conceptBoard.getName()};
//                process = Runtime.getRuntime().exec(parameterArray);
//                in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
//                stringBuffer = new StringBuffer();
//                actionStr = null;
//                while ((actionStr = in.readLine()) != null) {
//                    stringBuffer.append(actionStr);
//                    logger.info("接口返回值：" + actionStr);
//                }
//
//                if (StringUtils.isEmpty(stringBuffer.toString())){
//                    logger.warn("概念板块[" + conceptBoard.getName() + "]没有对应的股票");
//                    continue;
//                }
//
////                ConceptBoard updateConceptBoard = conceptBoardDao.findByName(conceptBoard.getName());
//                List<String> codeList = JSON.parseArray(stringBuffer.toString()).toJavaList(String.class);
////                stockInfoDao.updateConceptBoardIdByCodeList(codeList, updateConceptBoard.getId());
//
//                List<RelStockInfoConceptBoard> relStockInfoConceptBoardList = new ArrayList<>();
//                for (String code : codeList){
//                    StockInfo stockInfo = stockInfoDao.getStockInfoObjectByStockCode(code);
//                    ConceptBoard _conceptBoard = conceptBoardDao.findByName(conceptBoard.getName());
//                    if (null != stockInfo && null != _conceptBoard){
//                        RelStockInfoConceptBoard relStockInfoConceptBoard = new RelStockInfoConceptBoard();
//                        relStockInfoConceptBoard.setConceptBoardId(_conceptBoard.getId());
//                        relStockInfoConceptBoard.setStockInfoId(stockInfo.getId());
//                        relStockInfoConceptBoardList.add(relStockInfoConceptBoard);
//                    }else {
//                        logger.warn("stock_info表中，没有code为[" + code + "]的记录，或者concept_board表中没有name为[" + conceptBoard.getName() + "]，" +
//                                "因此不向表rel_stock_info_concept_board种添加记录");
//                    }
//                }
//                relStockInfoConceptBoardDao.batchSave(relStockInfoConceptBoardList);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                in.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            process.destroy();
//        }
//
//        logger.info("调用akshare接口，海量地保存数据（concept_board_index表和concept_board表），更新stock_info表的concept_board_id列完成");
//    }

    /**
     * 通过akShare，向表concept_board表和concept_board_index表添加新记录；删除rel_stock_info_concept_board表中的所有记录，然后添加记录
     */
    @Override
    public void writeConceptBoardAndConceptBoardIndexAndRelStockInfoConceptBoard_akShare_byDate() {
        logger.info("开始通过akShare，向表concept_board表和concept_board_index表添加记录；删除rel_stock_info_concept_board表中的所有记录，然后添加记录");

        String filePath = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.file.path");
        String findCurrentAllConceptBoardNameAndCode = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findCurrentAllConceptBoardNameAndCode");
        String findConceptBoardIndexByNameAndBeginDateAndEndDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findConceptBoardIndexByNameAndBeginDateAndEndDate");
        String beginDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findConceptBoardIndexByNameAndBeginDateAndEndDate.beginDate");
        String endDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findConceptBoardIndexByNameAndBeginDateAndEndDate.endDate");
        String findStockByConceptBoardCode = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"adam3.api.method.findStockByConceptBoardCode");

        Process process = null;
        BufferedReader in = null;
        try {
            // 调用adam3的接口，查询当前所有概念板块的name和code
            List<ConceptBoard> conceptBoardWithNameAndCodeList = null;
            String[] parameterArray = new String[]{"python", filePath, "api",  findCurrentAllConceptBoardNameAndCode};
            process = Runtime.getRuntime().exec(parameterArray);
            in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
            StringBuffer stringBuffer = new StringBuffer();
            String actionStr;
            while ((actionStr = in.readLine()) != null) {
                stringBuffer.append(actionStr);
                logger.debug("接口返回值：" + actionStr);
            }
            if (0 == stringBuffer.length()){
                logger.error("调用python接口findCurrentAllConceptBoardNameAndCode返回数据为空，停止程序");
                System.exit(-1);
            }

            // 解析
            conceptBoardWithNameAndCodeList = JSON.parseArray(stringBuffer.toString(), ConceptBoard.class);

            // 如果是新的概念板块，则插入ConceptBoard记录
            conceptBoardDao.batchSaveIfNotExist(conceptBoardWithNameAndCodeList);

            // 调用akshare接口，根据概念板块name，beginDate和endDate，查询ConceptBoardIndex记录
            for (ConceptBoard conceptBoard: conceptBoardWithNameAndCodeList){
                parameterArray = new String[]{"python", filePath, "api",  findConceptBoardIndexByNameAndBeginDateAndEndDate,
                        conceptBoard.getName(), conceptBoard.getMyquantCode(), beginDate, endDate};
                process = Runtime.getRuntime().exec(parameterArray);
                in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
                stringBuffer = new StringBuffer();
                actionStr = null;
                while ((actionStr = in.readLine()) != null) {
                    stringBuffer.append(actionStr);
                    logger.info("接口返回值：" + actionStr);
                }

                if (StringUtils.isEmpty(stringBuffer.toString())){
                    logger.warn("概念板块[" + conceptBoard.getName() + "," + conceptBoard.getMyquantCode() + "]在日期[" + beginDate + "]和[" + endDate + "]之间没有数据");
                    continue;
                }

                // 解析
                List<ConceptBoardIndex> insertConceptBoardIndexList = ModelConverter.stringToConceptBoardIndexList(stringBuffer.toString(), conceptBoard.getAkshareCode());

                // 批量插入ConceptBoardIndex对象
                if (null != insertConceptBoardIndexList && insertConceptBoardIndexList.size() > 0){
                    conceptBoardIndexDao.batchSave(insertConceptBoardIndexList);
                }
            }

            // 删除rel_stock_info_concept_board表中的所有记录
            relStockInfoConceptBoardDao.truncateTable();

            // 向表rel_stock_info_concept_board中添加记录，注意：有的股票可能在stock_info表中没有记录
            for (ConceptBoard conceptBoard: conceptBoardWithNameAndCodeList){
                parameterArray = new String[]{"python", filePath, "api",  findStockByConceptBoardCode, conceptBoard.getAkshareCode()};
                process = Runtime.getRuntime().exec(parameterArray);
                in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk"));
                stringBuffer = new StringBuffer();
                actionStr = null;
                while ((actionStr = in.readLine()) != null) {
                    stringBuffer.append(actionStr);
                    logger.info("接口返回值：" + actionStr);
                }

                if (StringUtils.isEmpty(stringBuffer.toString())){
                    logger.warn("概念板块[" + conceptBoard.getName() + "," + conceptBoard.getMyquantCode() + "]在日期[" + beginDate + "]和[" + endDate + "]之间没有数据");
                    continue;
                }

                List<String> codeList = JSON.parseArray(stringBuffer.toString()).toJavaList(String.class);

                List<RelStockInfoConceptBoard> relStockInfoConceptBoardList = new ArrayList<>();
                for (String code : codeList){
                    StockInfo stockInfo = stockInfoDao.getStockInfoObjectByStockCode(code);
                    ConceptBoard _conceptBoard = conceptBoardDao.findByName(conceptBoard.getName());
                    if (null != stockInfo && null != _conceptBoard){
                        RelStockInfoConceptBoard relStockInfoConceptBoard = new RelStockInfoConceptBoard();
                        relStockInfoConceptBoard.setConceptBoardId(_conceptBoard.getId());
                        relStockInfoConceptBoard.setStockInfoId(stockInfo.getId());
                        relStockInfoConceptBoardList.add(relStockInfoConceptBoard);
                    }else {
                        logger.warn("stock_info表中，没有code为[" + code + "]的记录，或者concept_board表中没有name为[" + conceptBoard.getName() + "]，" +
                                "因此不向表rel_stock_info_concept_board种添加记录");
                    }
                }
                relStockInfoConceptBoardDao.batchSave(relStockInfoConceptBoardList);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            process.destroy();
        }

        logger.info("通过akShare，向表concept_board表和concept_board_index表添加记录；删除rel_stock_info_concept_board表中的所有记录，然后添加记录完成");
    }

    /**
     * 海量计算last_close_price、change_range和change_amount字段
     */
    @Override
    public void writeConceptBoardIndexLastClosePrice() {
        logger.info("海量计算last_close_price、change_range和change_amount字段");

        conceptBoardIndexDao.writeConceptBoardIndexLastClosePrice();
    }

    /**
     * 海量计算KD指标
     */
    @Override
    public void writeConceptBoardIndexKD() {
        logger.info("海量计算KD指标");

        conceptBoardIndexDao.writeConceptBoardIndexKD();
    }

    /**
     * 增量计算last_close_price、change_range和change_amount字段
     */
    @Override
    public void writeConceptBoardIndexLastClosePriceByDate() {
        logger.info("增量计算last_close_price、change_range和change_amount字段");

        String beginDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"conceptBoardIndex.lastClosePrice.beginDate");
        String endDate = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"conceptBoardIndex.lastClosePrice.endDate");

        conceptBoardIndexDao.writeConceptBoardIndexLastClosePriceByDate(beginDate, endDate);
    }

    /**
     * 增量计算KD指标
     */
    @Override
    public void writeConceptBoardIndexKDByDate() {
        logger.info("增量计算KD指标");

        String date = PropertiesUtil.getValue(CONCEPT_BOARD_INDEX_PROPERTIES,"conceptBoardIndex.kd.date");

        conceptBoardIndexDao.writeConceptBoardIndexKDByDate(date);
    }
}
